package com.stm.bi.executor;

import com.stm.bi.jdbc.DataSourceEnum;
import com.stm.bi.jdbc.DataSourceSwitch;
import com.stm.framework.snowflake.Snowflake;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
import com.stm.framework.dto.Response;
import com.stm.bi.repository.report.SubjectCategoryRepository;
import com.stm.bi.dto.cmd.SubjectCategoryAdd;
import com.stm.bi.dto.cmd.SubjectCategoryUpd;
import com.stm.bi.repository.report.dataobject.SubjectCategoryDO;
import com.stm.framework.core.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.ArrayList;

/**
 * 科目分类-保存执行器
 *
 * @author qinyongjie
 * @date 2025-05-22
 */
@Component
public class SubjectCategorySaveExe {
    @Resource
    private SubjectCategoryRepository subjectCategoryRepository;

    //region 主体方法区

    /**
     * 保存
     *
     * @param subjectCategoryAdd
     */
    public Response create(SubjectCategoryAdd subjectCategoryAdd) {
        Long id = Snowflake.getInstance().nextId();
        subjectCategoryAdd.setId(id);

        // 父路径处理
        String path = buildPath(subjectCategoryAdd.getParentId());
        subjectCategoryAdd.setPath(path);

        boolean res = subjectCategoryRepository.create(subjectCategoryAdd);
        return Response.build(res);
    }

    /**
     * 更新
     *
     * @param subjectCategoryUpd
     */
    @DataSourceSwitch(DataSourceEnum.REPORT)
    @Transactional(rollbackFor = Exception.class)
    public Response update(SubjectCategoryUpd subjectCategoryUpd) {
        // 查询原有数据，检查父节点是否发生变化
        SubjectCategoryDO originalCategory = subjectCategoryRepository.getById(subjectCategoryUpd.getId());
        if (originalCategory == null) {
            return Response.failure("科目分类不存在");
        }

        // 父路径处理
        String newPath = buildPath(subjectCategoryUpd.getParentId());
        subjectCategoryUpd.setPath(newPath);

        // 更新当前节点
        boolean res = subjectCategoryRepository.update(subjectCategoryUpd);
        if (!res) {
            return Response.build(false);
        }

        // 检查父节点是否发生变化，如果变化则需要递归更新所有子节点的路径
        if (!originalCategory.getParentId().equals(subjectCategoryUpd.getParentId())) {
            updateChildrenPaths(subjectCategoryUpd.getId(), newPath);
        }

        return Response.build(true);
    }
    //endregion


    //region 方法区
    // 构建路径：根据父级ID查询父级路径，然后拼接当前ID
    private String buildPath(Long parentId) {
        if (parentId == null || parentId == 0) {
            // 如果没有父级，则路径为 "0"
            return "0";
        }

        // 查询父级信息
        SubjectCategoryDO parentCategory = subjectCategoryRepository.getById(parentId);
        if (parentCategory == null) {
            throw new RuntimeException("父级分类不存在，parentId: " + parentId);
        }

        String parentPath = parentCategory.getPath();
        if (StringUtil.isEmpty(parentPath)) {
            throw new RuntimeException("父级分类路径为空，parentId: " + parentId);
        }

        // 拼接路径：父级路径 + "," + 父级ID
        return parentPath + "," + parentId;
    }

    // 递归更新所有子节点的路径
    private void updateChildrenPaths(Long categoryId, String newParentPath) {
        // 查询当前节点的所有直接子节点
        LambdaQueryWrapper<SubjectCategoryDO> queryWrapper = Wrappers.<SubjectCategoryDO>lambdaQuery()
                .eq(SubjectCategoryDO::getParentId, categoryId);
        List<SubjectCategoryDO> children = subjectCategoryRepository.list(queryWrapper);

        if (children == null || children.isEmpty()) {
            return;
        }

        // 批量更新子节点的路径
        List<SubjectCategoryDO> updateList = new ArrayList<>();
        for (SubjectCategoryDO child : children) {
            // 构建子节点的新路径：父节点新路径 + "," + 当前节点ID
            String newChildPath = newParentPath + "," + categoryId;
            child.setPath(newChildPath);
            updateList.add(child);

            // 递归更新该子节点的所有子节点
            updateChildrenPaths(child.getId(), newChildPath);
        }

        // 批量更新数据库
        if (!updateList.isEmpty()) {
            subjectCategoryRepository.updateBatchById(updateList);
        }
    }
    //endregion

}
